using System;
using System.Collections.Generic;
using System.Text;
using MicroFractal.iTunesBrowser.Core.Device;
using MicroFractal.iTunesBrowser.Core.UBS;
using System.Runtime.InteropServices;
using System.Collections.ObjectModel;
using System.IO;
using System.Windows.Threading;
using System.Threading;

namespace MicroFractal.iTunesBrowser.Core
{
    
    public sealed class DeviceManager
    {

        Manzana.iPhone _iphone;
        Dispatcher _dispatcher;
        ObservableCollection<IDevice> devices;
        
        public DeviceManager()
        {
            _dispatcher = Dispatcher.CurrentDispatcher;
            GC.Collect();
            _iphone = new Manzana.iPhone();
            _iphone.Connect += new Manzana.ConnectEventHandler(_iphone_Connect);
            _iphone.Disconnect += new Manzana.ConnectEventHandler(_iphone_Disconnect);

            devices = GetConnectedDevices();
        }

        static DeviceManager _instance = new DeviceManager();
        public static DeviceManager Instance
        {
            get
            {
                return _instance;
            }
        }

        [STAThread]
        void _iphone_Disconnect(object sender, Manzana.ConnectEventArgs args)
        {
            _dispatcher.Invoke(DispatcherPriority.DataBind, (SendOrPostCallback)delegate { removeiPhone(args.Device.serial); }, args.Device.serial);
        }

        void removeiPhone(string serialId)
        {
            IDevice removeDevice = null;
            foreach (IDevice dev in devices)
            {
                if (serialId == dev.SerialID)
                {
                    removeDevice = dev;
                    break;
                }
            }
            if (removeDevice != null)
            {
                devices.Remove(removeDevice);
            }
        }

        [STAThread]
        void _iphone_Connect(object sender, Manzana.ConnectEventArgs args)
        {
            IPhoneDevice p = new IPhoneDevice((Manzana.iPhone)sender);
            _dispatcher.Invoke(DispatcherPriority.DataBind, (SendOrPostCallback)delegate { devices.Add(p); }, p);          
        }

        #region Methods

        public ObservableCollection<IDevice> Devices
        {
            get
            {
                return devices;
            }
        }

        public IDevice CreateFolderDevice(string folderPath)
        {
            BaseDevice f = null;
            try
            {
                f = new FolderDevice(Guid.NewGuid().ToString(), folderPath.Substring(folderPath.LastIndexOf("\\") + 1, folderPath.Length - folderPath.LastIndexOf("\\") - 1), folderPath);
            }
            catch
            {
                f = new SimpleFolderDevice(Guid.NewGuid().ToString(), folderPath.Substring(folderPath.LastIndexOf("\\") + 1, folderPath.Length - folderPath.LastIndexOf("\\") - 1), folderPath);
            }

            f.Disposed += new EventHandler(f_Disposed);

            devices.Add(f);

            return f;
        }

        void f_Disposed(object sender, EventArgs e)
        {
            try
            {
                devices.Remove((IDevice)sender);
                LibraryManager.RemoveLibrary((IDevice)sender);
            }
            catch
            {
                //TODO loguar error
            }

        }

        private  ObservableCollection<IDevice> GetConnectedDevices()
        {
            ObservableCollection<IDevice> result = new ObservableCollection<IDevice>();
            try
            {
                //System.Management.ObjectQuery q = new System.Management.ObjectQuery("Select * from Win32_PnPEntity WHERE Manufacturer like 'Apple%'");
                //System.Management.ManagementObjectSearcher s = new System.Management.ManagementObjectSearcher(q);
                //foreach (System.Management.ManagementObject mo in s.Get())
                //{
                //    foreach (System.Management.PropertyData p in mo.SystemProperties)
                //    {
                //        Console.WriteLine("{0} = {1}", p.Name, p.Value);
                //    }
                //    foreach (System.Management.PropertyData p in mo.Properties)
                //    {
                //        Console.WriteLine("{0} = {1}", p.Name, p.Value);
                //    }
                //    //Console.WriteLine("{0} = {1}", "quien", mo.Properties["Manufacturer"].Value);

                //    foreach (System.Management.ManagementObject b in mo.GetRelated("Win32_DiskPartition"))
                //    {
                //        Console.WriteLine("{0}", b["Name"]);
                //        foreach (System.Management.ManagementBaseObject c in b.GetRelated("Win32_LogicalDisk"))
                //        {
                //            if (c["DriveType"].ToString() == "2")
                //            {
                //                result.Add(new FolderDevice(c["VolumeSerialNumber"].ToString(), c["VolumeName"].ToString(), c["Caption"].ToString()));
                //            }
                //            //foreach(System.Management.PropertyData p in c.Properties)
                //            //{
                //            //    Console.WriteLine("{0} = {1}", p.Name, p.Value);
                //            //}
                //        }
                //    }
                //}

                using (System.Management.ManagementClass devs = new System.Management.ManagementClass(@"Win32_Diskdrive"))
                {
                    System.Management.ManagementObjectCollection moc = devs.GetInstances();
                    foreach (System.Management.ManagementObject mo in moc)
                    {
                        //Console.WriteLine(mo["DeviceId"]);
                        foreach (System.Management.PropertyData p in mo.SystemProperties)
                        {
                            Console.WriteLine("{0} = {1}", p.Name, p.Value);
                        }
                        foreach (System.Management.PropertyData p in mo.Properties)
                        {
                            Console.WriteLine("{0} = {1}", p.Name, p.Value);
                        }
                        if (mo.Properties["Caption"].Value.ToString().Contains("Apple"))
                        {
                            foreach (System.Management.ManagementObject b in mo.GetRelated("Win32_DiskPartition"))
                            {
                                Console.WriteLine("{0}", b["Name"]);
                                foreach (System.Management.ManagementBaseObject c in b.GetRelated("Win32_LogicalDisk"))
                                {
                                    if (c["DriveType"].ToString() == "2")
                                    {
                                        result.Add(new FolderDevice(c["VolumeSerialNumber"].ToString(), c["VolumeName"].ToString(), c["Caption"].ToString()));
                                    }
                                    //foreach(System.Management.PropertyData p in c.Properties)
                                    //{
                                    //    Console.WriteLine("{0} = {1}", p.Name, p.Value);
                                    //}
                                }
                            }
                        }
                    }
                }

                Manzana.iPhone iphone = new Manzana.iPhone();

            }
            catch { }
            return result;
        }

        //public static List<IDevice> GetConnectedDevices()
        //{

        //    List<IDevice> result = new List<IDevice>();
        //    APIHelper.SP_DEVINFO_DATA DeviceInfoData = new APIHelper.SP_DEVINFO_DATA();
        //    Guid g = Guid.Empty;
        //    string enumerator = "USBSTOR";

        //    IntPtr hdev = APIHelper.SetupDiGetClassDevs(ref g, Marshal.StringToBSTR(enumerator), IntPtr.Zero, APIHelper.DIGCF_ALLCLASSES);

        //    if (hdev.ToInt32() == APIHelper.INVALID_HANDLE_VALUE)
        //        return result;

        //    DeviceInfoData.cbSize = Marshal.SizeOf(typeof(APIHelper.SP_DEVINFO_DATA));
        //    for (int i = 0; APIHelper.SetupDiEnumDeviceInfo(hdev, i, ref DeviceInfoData); i++)
        //    {
        //        int DataT = 0;
        //        StringBuilder buffer = new StringBuilder("");
        //        buffer.Capacity = 512;
        //        int buffersize = 0;

        //        //
        //        // Call function with null to begin with, 
        //        // then use the returned buffer size (doubled)
        //        // to Alloc the buffer. Keep calling until
        //        // success or an unknown failure.
        //        //
        //        //  Double the returned buffersize to correct
        //        //  for underlying legacy CM functions that 
        //        //  return an incorrect buffersize value on 
        //        //  DBCS/MBCS systems.
        //        // 
        //        if (APIHelper.SetupDiGetDeviceRegistryProperty(
        //            hdev,
        //            ref DeviceInfoData,
        //            (int)APIHelper.SPDRP.SPDRP_FRIENDLYNAME,
        //             ref DataT,
        //             buffer,
        //            buffer.Capacity,
        //            ref buffersize))
        //        {
        //            if (!string.IsNullOrEmpty(buffer.ToString()))
        //            {
        //                if (buffer.ToString().Contains("Apple"))
        //                {
        //                    if (buffer.ToString().Contains("iPod"))
        //                    {

        //                    }
        //                    else
        //                    {
        //                        //result.Add(new IPhoneDevice(buffer.ToString()));
        //                    }
        //                }
        //            }
        //        }

        //        APIHelper.SetupDiDestroyDriverInfoList(hdev, ref DeviceInfoData, (int)0x00000002);

        //        Console.WriteLine("Result:[%s]\n", buffer);
        //    }


        //    if (Marshal.GetLastWin32Error() < 0)
        //    {
        //        return new List<IDevice>();
        //    }

        //    //  Cleanup
        //    APIHelper.SetupDiDestroyDeviceInfoList(hdev);

        //    return result;
        //}

        

        #endregion
    }

}
